/***************************************************************************
 *   Antc - library                                                        *
 *                                                                         *
 *   Copyright (C) 2008 by kuerant                                         *
 *                         <kuerant@gmail.com>                             *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This library is distributed in the hope that it will be usefull, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
 *   Library General Public License for more details.                      *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston,                *
 *   MA 02111-1307, USA                                                    *
 ***************************************************************************/

#include    "help/string.hpp"
#include    "help/microtime.hpp"

#include    "common/packet.hpp"
#include    "antc/antcudper.hpp"

using namespace std;
using namespace ant;
using namespace help;
using namespace zsocket;

namespace   antc
{
    
AntcUdper::AntcUdper()
    :   m_pChannel(NULL)
{
}

AntcUdper::~AntcUdper()
{
    if (NULL != m_pChannel) {
        delete m_pChannel;
    }
}


////////////////////////////////////////////////////////////////////////

void    
AntcUdper::connect( std::string server_address, int server_port ) throw (ant::Exception)
{
    if (NULL != m_pChannel) {
        throw ant::Exception("Already connected.");
    }
    
    m_pChannel = new UdpChannel(server_address, server_port);
}

void    
AntcUdper::disconnect( void ) throw (ant::Exception)
{
    if (NULL != m_pChannel) {
        delete m_pChannel;
        m_pChannel = NULL;
    }
}

void    
AntcUdper::join( std::string group ) throw (ant::Exception)
{
    throw ant::Exception("To Be Implemented", ANTC_ETOBEDONE);
}
    
void    
AntcUdper::leave( std::string group ) throw (ant::Exception)
{
    throw ant::Exception("To Be Implemented", ANTC_ETOBEDONE);
}
    
void    
AntcUdper::query( std::string group, std::vector<std::string>& result ) throw (ant::Exception)
{
    throw ant::Exception("To Be Implemented", ANTC_ETOBEDONE);
}
    
void    
AntcUdper::send( Message message, int timeout ) throw (ant::Exception)
{
    // step. check server address
    // step. message serialize
    // step. send data to server
    // step. wait ACK from server
    
    Packet  packet;
    if ( message.getDataSize() > packet.getBodyCapacity() ) {
        throw ant::Exception(String::format("Too much message data (size=%d packet-body-capacity=%d)", message.getDataSize(), packet.getBodyCapacity()), ANTC_EOVERFLOW);
    }
    
    packet.setDataPacketType();
    packet.setSerial();
    
    std::string&    data = message.getData();
    packet.setBody(data.c_str(), data.size());
    
    m_pChannel->send(packet, timeout);
}
    
void    
AntcUdper::recv( Message& message, int timeout ) throw (ant::Exception)
{
    // step. receive data from server
    // step. unserialize to message
    // step. send ACK to server
    
    Packet  packet;
    m_pChannel->recv(packet, timeout);
    
    message.setData(packet.getPack(), packet.getPackSize());
}

    
}   // namespace antc
